/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.celiosilva.simbanc.dao;

import com.celiosilva.simbanc.arquitetura.PropriedadesSistema;
import com.celiosilva.simbanc.exceptions.SistemaException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 *
 * @author celio@celiosilva.com
 */
public class FileDao<PK extends Serializable,V extends Serializable> implements Dao<PK,V> {

    private final           GravadorSerial<Map<PK,V>>    gravador;
    private                 Map<PK,V>                       dados;

    public FileDao(Class<?> classe) throws SistemaException {
        File diretorio = new File(PropriedadesSistema.DIRETORIO_DAO.getValor());
        gravador = new GravadorSerial(diretorio, classe.getSimpleName());
        this.dados = this.lerMap();
    }

    private void gravarMap() throws SistemaException {
        try {
            this.gravador.gravarEmArquivo(dados);
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new SistemaException("", ex);
        }
    }

    private Map<PK,V> lerMap() throws SistemaException {
        try {
            Map<PK,V> map = this.gravador.lerDoArquivo();
            if (map == null)
                map = new HashMap<PK, V>();
            return map;
        } catch (Exception ex) {
            ex.printStackTrace();
            if (ex instanceof FileNotFoundException)
                return new HashMap<PK, V>();
            throw new SistemaException("", ex);
        }
    }

    @Override
    public int size() {
        return dados.size();
    }

    @Override
    public boolean isEmpty() {
        return dados.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return dados.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return dados.containsValue(value);
    }

    @Override
    public V get(Object key) {
        return dados.get(key);
    }

    @Override
    public V put(PK key, V value) {
        return dados.put(key, value);
    }

    @Override
    public V remove(Object key) {
        return dados.remove(key);
    }

    @Override
    public void putAll(Map<? extends PK, ? extends V> m) {
        dados.putAll(m);
    }

    @Override
    public void clear() {
        dados.clear();
    }

    @Override
    public Set<PK> keySet() {
        return dados.keySet();
    }

    @Override
    public Collection<V> values() {
        return dados.values();
    }

    @Override
    public Set<Entry<PK, V>> entrySet() {
        return dados.entrySet();
    }

    @Override
    public void commit() throws SistemaException{
        this.gravarMap();
    }
    
}
